package com.iemp.service.impl.list.security;

import com.iemp.bean.example.AccountExample;
import com.iemp.bean.impl.Account;
import com.iemp.dao.AccountMapper;
import com.iemp.exception.entity.universal.CustomNotFoundException;
import com.iemp.service.base.AbstractListService;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

@Service
public class AccountServiceImpl extends AbstractListService<Account> implements UserDetailsService {

    private final AccountMapper mapper;
    private final BCryptPasswordEncoder bCryptPasswordEncoder;

    public AccountServiceImpl(AccountMapper mapper, BCryptPasswordEncoder bCryptPasswordEncoder) {
        this.mapper = mapper;
        this.bCryptPasswordEncoder = bCryptPasswordEncoder;
    }

    @Override
    public List findAllByList() {
        return mapper.selectByExample(new AccountExample());
    }

    @Override
    public Integer deleteById(Integer id) {
        return mapper.deleteByPrimaryKey(id);
    }

    @Override
    public Account selectById(Integer id) {
        return mapper.selectByPrimaryKey(id);
    }

    @Override
    public int insertSelective(Account entity) {
        entity.setPassword(bCryptPasswordEncoder.encode(entity.getPassword()));
        return mapper.insertSelective(entity);
    }

    @Override
    public int updateByIdSelective(Account entity) {
        return mapper.updateByPrimaryKeySelective(entity);
    }

    @Override
    public UserDetails loadUserByUsername(String accountName) throws UsernameNotFoundException {
        AccountExample example = new AccountExample();
        example.createCriteria().andAccountnameEqualTo(accountName);
        List<Account> accounts = mapper.selectByExample(example);
        if (accounts.size() == 0) {
            log.error("account not found in the database:{}", accountName);
            throw new CustomNotFoundException("User not found in the database:" + accountName);
        } else {
            log.info("account found in the database:{}", accountName);
        }
        Account account = accounts.get(0);
        Collection<SimpleGrantedAuthority> authorities = new ArrayList<>();
        authorities.add(new SimpleGrantedAuthority(account.getAccountRoleId().toString()));
        return new User(account.getName(), account.getPassword(), authorities);
    }


}
